package controllers

import (
	"GoWeb_Advanced/00_bluebell/models"
	"fmt"
	"reflect"
	"strings"

	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	"github.com/go-playground/validator/v10"

	ut "github.com/go-playground/universal-translator"
	enTranslations "github.com/go-playground/validator/v10/translations/en"
	zhTranslations "github.com/go-playground/validator/v10/translations/zh"
)

// 定义一个全局的翻译器 T
var trans ut.Translator

func InitTrans(locale string) (err error) {
	//修改 gin 框架中的 Validator 引擎属性，实现自定制
	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {

		//注册一个获取 json tag 的自定义方法（否则前端显示的错误中的 json 字段名就会是 定义的结构体的字段名，而不是我们所传入的 json 名）
		v.RegisterTagNameFunc(func(field reflect.StructField) string {
			name := strings.SplitN(field.Tag.Get("json"), ",", 2)[0]
			if name == "-" {
				return ""
			}
			return name
		})
		/*
			从 {"msg": {"ParamSignUp.RePassword": "RePassword为必填字段"}} 变为：
			   {"msg": {"ParamSignUp.re_password": "re_password为必填字段"}}
		*/

		//为 SignUpParam 注册自定义校验方法
		v.RegisterStructValidation(SignUpParamsStructLevelValidation, models.ParamSignUp{})

		zhT := zh.New() //中文翻译器
		enT := en.New() //英文翻译器

		//第一个参数是备用（fallback）的语言环境
		//后面的参数是应该支持的语言环境（支持多个）
		//uni := ut.New(zhT,zhT) 也是可以的
		uni := ut.New(enT, zhT, enT)

		//locale 通常取决于 http 请求头的 'Accept-Language'
		var ok bool
		//也可以使用 uni.FindTranslator(...) 传入多个 locale 进行查找
		trans, ok = uni.GetTranslator(locale)
		if !ok {
			return fmt.Errorf("uni.GetTranslator(%s) failed", locale)
		}

		//注册翻译器
		switch locale {
		case "en":
			err = enTranslations.RegisterDefaultTranslations(v, trans)
		case "zh":
			err = zhTranslations.RegisterDefaultTranslations(v, trans)
		default:
			err = enTranslations.RegisterDefaultTranslations(v, trans)

		}
		return
	}
	return
}

// removeTopStruct 去除提示信息中的结构体名称
func removeTopStruct(fields map[string]string) map[string]string {
	res := map[string]string{}
	for field, err := range fields {
		res[field[strings.Index(field, ".")+1:]] = err
	}
	return res
}

/*
	从 {"msg": {"ParamSignUp.re_password": "re_password为必填字段"}} 变为了：
       {"msg": {"re_password": "re_password为必填字段"}}
*/

func SignUpParamsStructLevelValidation(sl validator.StructLevel) {
	su := sl.Current().Interface().(models.ParamSignUp)

	if su.Password != su.RePassword {
		//输出错误提示信息，最后一个参数就是传递的 param
		sl.ReportError(su.RePassword, "re_password", "RePassword", "eqfield", "password")
	}
}

/*
	从 {"msg": {"re_password": "re_password必须等于Password"}} 变为了：
	   {"msg": {"re_password": "re_password必须等于password"}}
*/
